package com.ztrue.framework.context;

import com.ztrue.framework.core.command.CommandMessage;
import com.ztrue.framework.core.command.ICommand;
import com.ztrue.framework.core.domain.IAggregateRootCache;
import com.ztrue.framework.core.event.IEventService;
import com.ztrue.framework.core.event.impl.MongoDBEventStore;
import com.ztrue.framework.disruptor.DisruptorCommandBus;
import com.ztrue.framework.disruptor.MessageHandler;
import com.ztrue.framework.handler.IHandlerDefinitionRegistry;
import com.ztrue.framework.handler.IHandlerRegistry;
import com.ztrue.common.properties.Proper;
import com.ztrue.common.utilities.Assert;

/**
 * 默认命令消息转发处理器
 *
 * @author zhangw
 * @date 2016/12/2 15:00
 */
public class DefaultProcessingCommandHandler implements IProcessingMessageHandler {
    /**
     * 消息发送总线
     */
    private ICommandTransmit transmitBus;
    /**
     * 命令消息处理器
     */
    private final MessageHandler<CommandMessage> commandMessageHander;
    /**
     * 处理器注册表
     */
    private final IHandlerRegistry handlerRegistry;
    /**
     * 处理器定义注册表
     */
    private final IHandlerDefinitionRegistry handlerDefinitionRegistry;
    /**
     * 事件服务
     */
    private final IEventService eventService;
    /**
     * 聚合跟缓存
     */
    private final IAggregateRootCache aggregateRootCache;

    public DefaultProcessingCommandHandler() {
        this.handlerRegistry = ApplicationContextProvider.APPLICATIONCONTEXT.getHandlerRegistry();
        this.handlerDefinitionRegistry = ApplicationContextProvider.APPLICATIONCONTEXT.getHandlerDefinitionRegistry();
        this.aggregateRootCache = ApplicationContextProvider.APPLICATIONCONTEXT.getAggregateRootCache();
        this.eventService = getEventService();

        String ibus = Proper.get("command.queue.bus", "disruptor");
        commandMessageHander = getCommandMessageHander();
        switch (ibus) {
            case "disruptor":
                transmitBus = new DisruptorCommandBus(commandMessageHander);
                break;
        }
        Assert.notNull(transmitBus, "无法创建命令处理总线");
    }

    /**
     * 获取领域事件服务
     *
     * @return
     */
    public IEventService getEventService() {
        return new DefaultEventService(handlerRegistry, handlerDefinitionRegistry, new MongoDBEventStore(), aggregateRootCache);
    }

    /**
     * 处理消息
     *
     * @param command
     */
    @Override
    public void handler(ICommand command) {
        transmitBus.send(command);
    }

    /**
     * 获取命令消息处理器
     *
     * @return
     */
    private MessageHandler<CommandMessage> getCommandMessageHander() {
        return new DefaultCommandMessageHander(handlerRegistry, handlerDefinitionRegistry, eventService);
    }

    /**
     * 获取命令发送总线
     *
     * @return
     */
    protected ICommandTransmit getTransmitBus() {
        return transmitBus;
    }
}
